using System.Threading;

namespace PaulRz.Util.Patterns
{
    /// <summary>
    /// Active object with parametrized worker method
    /// </summary>
    public abstract class ParametrizedActiveObject : IRunnable
    {
        private int joinTime = 1000;
        protected string name;
        protected Thread thread;
        protected object parameter;
        
        protected ParametrizedActiveObject(string name, object parameter)
        {
            this.name = name;
            this.parameter = parameter;
        }
        
        protected ParametrizedActiveObject(string name, object parameter, int joinTime) : this(name, parameter)
        {
            this.joinTime = joinTime;
        }

        /// <summary>
        /// Get or Set if the object is in background mode
        /// </summary>
        public bool IsBackground
        {
            get { return isBackground; }
            set { isBackground = value; }
        }

        /// <summary>
        /// Get if the object is stopping
        /// </summary>
        public bool IsStopping
        {
            get { return isStopping; }
        }

        /// <summary>
        /// Get if the object has been stopped
        /// </summary>
        public bool Stopped
        {
            get 
            { 
                if (thread==null)
                {
                    return true;
                }
                else
                {
                    return !thread.IsAlive;
                }
            }
        }

        /// <summary>
        /// Starts the activity of the object
        /// </summary>
        public void Start()
        {
            if (thread == null || thread.IsAlive)
            {
                thread = new Thread(new ParameterizedThreadStart(Run));
                thread.Name = name;
                thread.IsBackground = IsBackground;
            }
            isStopping = false;
            thread.Start(parameter);
        }

        private bool isStopping = false;
        private bool isBackground = true;

        /// <summary>
        /// Main worker method
        /// </summary>
        /// <param name="parameter"></param>
        protected abstract void Run(object parameter);

        /// <summary>
        /// Stops the activity of the object
        /// </summary>
        public void Stop()
        {
            isStopping = true;
            if (!thread.Join(joinTime))
                thread.Abort();
        }
    }
}
